package com.logic.service.impl;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

import javax.inject.Named;

import com.database.bean.CompanyRoundDecisionAndResult;
import com.database.bean.Setting;
import com.database.bean.User;
import com.logic.service.UserService;
import com.security.util.SecurityUtil;

@Named
public class UserServiceImpl extends BaseServiceImpl implements Serializable, UserService {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public boolean createUser(String firstname, String lastname,
			String nickname, String email, String password) {
		try {
			if (firstname == null || firstname.isEmpty() || lastname == null
					|| lastname.isEmpty() || nickname == null
					|| nickname.isEmpty() || email == null || email.isEmpty()
					|| password == null || password.isEmpty())
				return false;
			logger.trace("Entered Create User");
			Setting setting = this.getSetting();
			User user = new User();
			byte[] bSalt = SecurityUtil.createSalt();
			String salt = SecurityUtil.encodeBase64(bSalt);
			byte[] bDigest = SecurityUtil.getHash(password, bSalt);
			String digest = SecurityUtil.encodeBase64(bDigest);
			user.setEmail(email);
			user.setNickname(nickname);
			user.setPassword(digest);
			user.setSalt(salt);
			user.setBudget(setting.getStartBudgetForCompanies());
			user.setImageValue(setting.getStartImageForCompanies());
			userDao.create(user);
			return true;
		} catch (UnsupportedEncodingException ex) {
			logger.error("Encoding is not supportet: " + ex.getMessage());
			return false;
		} catch (NoSuchAlgorithmException ex) {
			logger.error("Algorithm is not supportet: " + ex.getMessage());
			return false;
		}
	}

	public void updateUser(User user) {
		userDao.update(user);
	}

	public User getUserByNickname(String nickname){
		return userDao.getUserByNickname(nickname);
	}
	
	public User login(String nickname, String password) {
		User user = userDao.getUserByNickname(nickname);
		String digest, salt;
		boolean userExists;
		// first if for prevention of side channel attack
		if (user == null) {
			digest = "000000000000000000000000000=";
			salt = "00000000000=";
			userExists = false;
		} else {
			digest = user.getPassword();
			salt = user.getSalt();
			userExists = true;
		}

		try {
			return (SecurityUtil.authenticate(digest, password, salt) && userExists) ? user : null;
		} catch (UnsupportedEncodingException ex) {
			logger.error("Encodeing is not supportet: " + ex.getMessage());
			return null;
		} catch (NoSuchAlgorithmException ex) {
			logger.error("Algorithm is not supportet: " + ex.getMessage());
			return null;
		}
	}

	public boolean isNicknameUsed(String nickname) {
		if (userDao.getUserByNickname(nickname) != null)
			return true;
		else
			return false;

	}
	
	public List<User> getAllUsers(){
		return userDao.getAll();
	}
	
	public boolean deleteUser(User user){
		userDao.delete(user);
		return true;
	}
	
	public User reloadCompanyRoundDecisionAndResults(User user){
		return this.userDao.reloadCompanyRoundDecisionAndResults(user);
	}
	
	public User reloadGame(User user){
		return this.userDao.reloadGame(user);
	}
	
	public CompanyRoundDecisionAndResult reloadReportDecisions(CompanyRoundDecisionAndResult crDecRes){
		return this.companyRoundDecisionAndResultDao.reloadReportDecisions(crDecRes);
	}

}
